package cool.taomu.toolkit.rpc.thrift.service

import java.util.function.Function
import org.apache.commons.pool2.BasePooledObjectFactory
import org.apache.commons.pool2.PooledObject
import org.apache.commons.pool2.impl.AbandonedConfig
import org.apache.commons.pool2.impl.DefaultPooledObject
import org.apache.commons.pool2.impl.GenericObjectPool
import org.apache.commons.pool2.impl.GenericObjectPoolConfig
import org.apache.thrift.transport.TSocket
import org.apache.thrift.transport.TTransport
import org.slf4j.LoggerFactory

class ThriftConnectionFactory extends BasePooledObjectFactory<TTransport> {
	val static LOG = LoggerFactory.getLogger(ThriftConnectionFactory);

	String host;
	int port;
	int timeout;

	val Function<TTransport, Boolean> client;

	def getObjectPool(GenericObjectPoolConfig<TTransport> config) {
		var AbandonedConfig abandonedConfig = new AbandonedConfig();
		abandonedConfig.setRemoveAbandonedOnBorrow(true);
		abandonedConfig.setLogAbandoned(true);
		new GenericObjectPool<TTransport>(this, config,abandonedConfig)
	}

	new(String host, int port) {
		this(host, port, 30000, null)
	}

	new(String host, int port, int timeout) {
		this(host, port, timeout, null)
	}

	new(String host, int port, Function<TTransport, Boolean> client) {
		this(host, port, 30000, client)
	}

	new(String host, int port, int timeout, Function<TTransport, Boolean> client) {
		this.host = host;
		this.port = port;
		this.timeout = timeout;
		this.client = client;
	}

	override create() throws Exception {
		LOG.debug("创建host:{},port:{},timeout:{}连接", this.host, this.port, this.timeout);
		var transport = new TSocket(host, port);
		transport.timeout = this.timeout
		transport.open();
		return transport;
	}

	override wrap(TTransport transport) {
		return new DefaultPooledObject<TTransport>(transport);
	}

	override destroyObject(PooledObject<TTransport> p) throws Exception {
		LOG.debug("销毁连接");
		var TTransport transport = p.getObject();
		if (transport !== null && transport.isOpen()) {
			transport.close(); // 关闭连接
		}
	}

	override validateObject(PooledObject<TTransport> p) {
		var TTransport transport = p.getObject();
		var res = transport !== null && transport.isOpen();
		LOG.debug("验证链接是否有效:{}", res);
		if (res) {
			if (client !== null) {
				return client.apply(transport);
			}
		}
		return false;
	}

	override activateObject(PooledObject<TTransport> p) throws Exception {
		LOG.debug("激活对象");
		var TTransport transport = p.getObject();
		if (!transport.isOpen()) {
			LOG.debug("重新连接");
			transport.open();
		}
	}

	override passivateObject(PooledObject<TTransport> p) throws Exception {
		LOG.debug("归还对象");
		var TTransport transport = p.getObject();
		if (!transport.isOpen()) {
			LOG.debug("重新连接");
			transport.open();
		}
	}
}
